package com.greet.service.impl;

import com.greet.constant.StatusConstant;
import com.greet.entity.Orders;
import com.greet.mapper.DishMapper;
import com.greet.mapper.OrdersMapper;
import com.greet.mapper.SetmealMapper;
import com.greet.mapper.UserMapper;
import com.greet.service.WorkspaceService;
import com.greet.vo.BusinessDataVO;
import com.greet.vo.DishOverViewVO;
import com.greet.vo.OrderOverViewVO;
import com.greet.vo.SetmealOverViewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private DishMapper dishMapper;

    @Override
    public BusinessDataVO businessData(LocalDate date) {
        LocalDateTime begin = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(date, LocalTime.MAX);
        Integer newUserCount = userMapper.countUser(begin, end);
        Integer orderCountAll = ordersMapper.count(begin, end, null);
        Integer validOrderCount = ordersMapper.count(begin, end, Orders.COMPLETED);

        Double orderCompletionRate;
        if (orderCountAll == 0)orderCompletionRate = Double.valueOf(1);
        else orderCompletionRate = validOrderCount.doubleValue() / orderCountAll.doubleValue();

        Double turnover = Double.valueOf(0.0);
        Double unitPrice = Double.valueOf(0.0);
        BigDecimal turnoverBig = ordersMapper.sumTurnoverByDate(begin, end);
        if (turnoverBig != null)turnover = turnoverBig.doubleValue();
        BigDecimal unitPriceBig = ordersMapper.averageAmount(begin, end, Orders.COMPLETED);
        if (unitPriceBig != null)unitPrice = unitPriceBig.doubleValue();
        BusinessDataVO dataVO = BusinessDataVO.builder()
                .newUsers(newUserCount)
                .orderCompletionRate(orderCompletionRate)
                .turnover(turnover)
                .unitPrice(unitPrice)
                .validOrderCount(validOrderCount).build();

        return dataVO;
    }

    @Override
    public SetmealOverViewVO overviewSetmeals() {
        Long all = setmealMapper.countAll();
        Integer sold = setmealMapper.countByStatus(StatusConstant.ENABLE);
        Integer discontinued = all.intValue() - sold;
        SetmealOverViewVO viewVO = new SetmealOverViewVO(sold, discontinued);
        return viewVO;
    }

    @Override
    public DishOverViewVO overviewDishes() {
        Long all = dishMapper.countAll();
        Integer sold = dishMapper.countByStatus(StatusConstant.ENABLE);
        Integer discontinued = all.intValue() - sold;
        DishOverViewVO viewVO = new DishOverViewVO(sold, discontinued);
        return viewVO;
    }

    @Override
    public OrderOverViewVO overviewOrders(LocalDate date) {
        LocalDateTime begin = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(date, LocalTime.MAX);

        Integer allOrders = ordersMapper.countByStatus(begin, end, null);
        Integer cancelledOrders = ordersMapper.countByStatus(begin, end, Orders.CANCELLED);
        Integer completedOrders = ordersMapper.countByStatus(begin, end, Orders.COMPLETED);
        Integer deliveredOrders = ordersMapper.countByStatus(begin, end, Orders.CONFIRMED);
        Integer waitingOrders = allOrders - cancelledOrders - completedOrders - deliveredOrders;

        OrderOverViewVO viewVO = OrderOverViewVO.builder()
                .allOrders(allOrders)
                .cancelledOrders(cancelledOrders)
                .completedOrders(completedOrders)
                .deliveredOrders(deliveredOrders)
                .waitingOrders(waitingOrders).build();
        return viewVO;
    }
}
